package com.followerback.resources;

import java.util.List;
import java.util.logging.Logger;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.auth.AccessToken;

import com.followerback.model.MatchedFollower;
import com.followerback.model.TwitterProfile;
import com.googlecode.objectify.Objectify;
import com.googlecode.objectify.ObjectifyService;

@Path("/friend")
public class FriendResource extends Resource {
	
	private static final Logger logger = Logger.getLogger(FriendResource.class.getName());
	
	@Path("/follow/{id}")
	@POST
	@Produces(MediaType.APPLICATION_JSON)
	public Response follow(@PathParam("id") @DefaultValue("-1") long id, 
			@Context HttpServletRequest request) {
		
		
		/* Initial stuff */
		logger.info("Entering follow");
		long methodStartTime = System.currentTimeMillis();
		HttpSession httpSession = request.getSession(true);
		Long userID = (Long)httpSession.getAttribute("serverSideUserID");
		if(userID == null) {
			String errorReason = "User not logged in";
			logger.severe(errorReason);
			return Response.status(401).build();
		}
		if(id == -1) {
			String errorReason = "Missing required params";
			logger.severe(errorReason);
			return Response.serverError().entity("Missing required params").build();
		}
		Objectify objectify = ObjectifyService.begin();
		Twitter twitter = twitterFactory.getInstance();
		
		
		/* Get DB Objects */
		// get user profile
		TwitterProfile twitterProfile = objectify.find(TwitterProfile.class, userID);
		if(twitterProfile == null) {
			String errorReason = "User not logged in";
			logger.severe(errorReason);
			return Response.status(401).build();
		}
		
		// create access token
		AccessToken accessToken = new AccessToken(twitterProfile.getToken(), 
				twitterProfile.getTokenSecret());
		twitter.setOAuthAccessToken(accessToken);
		
		// get matchFollower
		MatchedFollower matchedFollower = objectify.find(MatchedFollower.class, id);
		if(matchedFollower == null) {
			String errorReason = "Match not found";
			logger.severe(errorReason);
			return Response.serverError().entity("Missing required params").build();
		}
		
		
		/* Follow Match */
		// create friendship
		try {
			twitter.createFriendship(matchedFollower.getScreenName());
		} catch (TwitterException e) {
			logger.severe(e.getErrorMessage());
			return Response.serverError().entity(e.getErrorMessage()).build();
		}
		
		// delete match
		objectify.delete(matchedFollower);
		
		
		/* End Stuff */
		logger.info("Exiting follow in " +(System.currentTimeMillis() - methodStartTime)/1000d+ " secs");
		return Response.ok().build();
	}
	
	@Path("/remove/{id}")
	@DELETE
	@Produces(MediaType.APPLICATION_JSON)
	public Response remove(@PathParam("id") @DefaultValue("-1") long id, 
			@Context HttpServletRequest request) {
		
		
		/* Initial stuff */
		logger.info("Entering remove");
		long methodStartTime = System.currentTimeMillis();
		HttpSession httpSession = request.getSession(true);
		Long userID = (Long)httpSession.getAttribute("serverSideUserID");
		if(userID == null) {
			String errorReason = "User not logged in";
			logger.severe(errorReason);
			return Response.status(401).build();
		}
		if(id == -1) {
			String errorReason = "Missing required params";
			logger.severe(errorReason);
			return Response.serverError().entity("Missing required params").build();
		}
		Objectify objectify = ObjectifyService.begin();
		
		
		/* Get DB Objects */
		MatchedFollower matchedFollower = objectify.find(MatchedFollower.class, id);
		if(matchedFollower == null) {
			String errorReason = "Match not found";
			logger.severe(errorReason);
			return Response.serverError().entity("Missing required params").build();
		}
		
		
		/* Remove Match */
		objectify.delete(matchedFollower);
		
		
		/* End Stuff */
		logger.info("Exiting remove in " +(System.currentTimeMillis() - methodStartTime)/1000d+ " secs");
		return Response.ok().build();
	}
	
	@Path("/save/{id}")
	@POST
	@Produces(MediaType.APPLICATION_JSON)
	public Response saveFriends(@PathParam("id") @DefaultValue("-1") long id) {
		
		
		/* Initial stuff */
		logger.info("Entering saveFriends");
		long methodStartTime = System.currentTimeMillis();
		if(id == -1) {
			String errorReason = "Missing required params";
			logger.severe(errorReason);
			return Response.ok().build();
		}
		Objectify objectify = ObjectifyService.begin();
		Twitter twitter = twitterFactory.getInstance();
		
		
		/* Get Access Token */
		// get twitter profile
		TwitterProfile twitterProfile = objectify.find(TwitterProfile.class, id);
		if(twitterProfile == null) {
			String errorReason = "Twitter profile not found";
			logger.severe(errorReason);
			return Response.ok().build();
		}
		
		// create access token
		AccessToken accessToken = new AccessToken(twitterProfile.getToken(), 
				twitterProfile.getTokenSecret());
		twitter.setOAuthAccessToken(accessToken);
		
		
		/* Save Connections */
		List<Long> friendIDs = getFriendIDs(twitter, null);
		long twitterProfileID = twitterProfile.getId();
		for(Long friendID : friendIDs) {
			try {
				saveConnection(objectify, friendID, twitter, twitterProfileID);
			} catch (TwitterException e) {
				logger.severe(e.getErrorMessage());
				return Response.ok().build();
			}
		}
		
		/* End Stuff */
		logger.info("Exiting saveFriends in " 
				+(System.currentTimeMillis() - methodStartTime)/1000d+ " secs");
		return Response.ok().build();
	}

}
